
#include "TankWar1.h"
#include "MatrixConvert.h"
#include "TrigMath.h"

#include "ObjInst.h"
#include "AppEnv.h"

#include "RgbTable.h"

// create some constants for ease of access
#define AMBIENT_LIGHT_INDEX   0 // ambient light index
#define INFINITE_LIGHT_INDEX  1 // infinite light index
#define POINT_LIGHT_INDEX     2 // point light index
#define SPOT_LIGHT_INDEX      3 // spot light index


CTankWar1::CTankWar1()
{
	float init[] = {0,40,0,1};

	init[0] = 0;
	init[1] = 40;
	init[2] = 0;
	init[3] = 1;
	cam_pos		= init;

	init[0] = 0;
	init[1] = 0;
	init[2] = 0;
	init[3] = 1;
	cam_dir		= init;

	init[0] = 0;
	init[1] = 0;
	init[2] = 0;
	init[3] = 1;
	cam_target	= init;

	init[0] = 1.0;
	init[1] = 1.0;
	init[2] = 1.0;
	init[3] = 1;
	vscale	= init;

	init[0] = 0;
	init[1] = 0;
	init[2] = 0;
	init[3] = 1;
	vpos	= init;

	init[0] = 0;
	init[1] = 0;
	init[2] = 0;
	init[3] = 1;
	vrot	= init;
}
	
CTankWar1::~CTankWar1()
{

}

int CTankWar1::Game_Init()
{
	// this function is where you do all the initialization 
	// for your game

	int index; // looping var

	memset(CObjInst<Debug_Info_Frame>::Inst(), 0, sizeof(Debug_Info_Frame));

	// start up DirectDraw (replace the parms as you desire)
	int nRet = m_ddraw.Init(m_hWnd, m_WndWidth, m_WndHeight, m_bpp, m_bFullScreen);
	//if (nRet != 0)
	//	return-1;

	m_graphGdi.Init(&m_ddraw);

	// initialize directinput
	m_gameInput.Init(m_hInstance, m_hWnd);

	// acquire the keyboard 
	m_gameInput.Init_Keyboard();


	// initialize directsound and directmusic
	m_gameSound.Init(m_hWnd);
	m_gameMusic.Init(m_hWnd, m_gameSound.GetDSound());

	// hide the mouse
	ShowCursor(FALSE);

	// seed random number generator
	srand(m_gameClock.Start_Clock());

	//
	CTrigMath::Build_Sin_Cos_Tables();


	// initialize the camera with 90 FOV, normalized coordinates
	cam.Init(
		CAM_MODEL_EULER, // euler camera model
		cam_pos,  // initial camera position
		cam_dir,  // initial camera angles
		cam_target,      // no initial target
		200,      // near and far clipping planes
		12000.0,
		90.0,      // field of view in degrees
		m_WndWidth,   // size of final screen viewport
		m_WndHeight);

	CObjInst<CAppEnv>::Inst()->Init();
	tstring strBasePath = CObjInst<CAppEnv>::Inst()->m_strAppPath + _T("../../res/");

	// load the master tank object
	tstring strPath = strBasePath + _T("tank3.plg");
	vscale.SetX(0.75);
	vscale.SetY(0.75);
	vscale.SetZ(0.75);
	m_plgFile.Init((TCHAR*)strPath.c_str());
	m_plgFile.LoadObject(obj_tank, &vscale, &vpos, &vrot);


	// load player object for 3rd person view
	strPath = strBasePath + _T("tank2.plg");
	vscale.SetX(0.75);
	vscale.SetY(0.75);
	vscale.SetZ(0.75);
	m_plgFile.Init((TCHAR*)strPath.c_str());
	m_plgFile.LoadObject(obj_player, &vscale, &vpos, &vrot);


	// load the master tower object
	strPath = strBasePath + _T("tower1.plg");
	vscale.SetX(1.0);
	vscale.SetY(2.0);
	vscale.SetZ(1.0);
	m_plgFile.Init((TCHAR*)strPath.c_str());
	m_plgFile.LoadObject(obj_tower, &vscale, &vpos, &vrot);


	// load the master ground marker
	strPath = CObjInst<CAppEnv>::Inst()->m_strAppPath + _T("marker1.plg");
	vscale.SetX(3.0);
	vscale.SetY(3.0);
	vscale.SetZ(3.0);
	m_plgFile.Init((TCHAR*)strPath.c_str());
	m_plgFile.LoadObject(obj_marker, &vscale, &vpos, &vrot);


	// position the tanks
	for (index = 0; index < NUM_TANKS; index++)
	{
		// randomly position the tanks
		tanks[index].vector[X] = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
		tanks[index].vector[Y] = 0; // obj_tank.max_radius;
		tanks[index].vector[Z] = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
		tanks[index].vector[W] = RAND_RANGE(0,360);
	} // end for


	// position the towers
	for (index = 0; index < NUM_TOWERS; index++)
	{
		// randomly position the tower
		towers[index].vector[X] = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
		towers[index].vector[Y] = 0; // obj_tower.max_radius;
		towers[index].vector[Z] = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
	} // end for

	//==
	// set up lights
	lightMgr.Reset();
	lightMgr.Init((PDxDrawEnv)&m_ddraw);

	// create some working colors
	RGBAV1 white, gray, black, red, green, blue;

	white.rgba = _RGBA32BIT(255,255,255,0);
	gray.rgba  = _RGBA32BIT(100,100,100,0);
	black.rgba = _RGBA32BIT(0,0,0,0);
	red.rgba   = _RGBA32BIT(255,0,0,0);
	green.rgba = _RGBA32BIT(0,255,0,0);
	blue.rgba  = _RGBA32BIT(0,0,255,0);

	// ambient light
	CPoint4d posL;
	CVector4d dirL;
	lightMgr[AMBIENT_LIGHT_INDEX]->Init(
		AMBIENT_LIGHT_INDEX,   
		LIGHTV1_STATE_ON,      // turn the light on
		LIGHTV1_ATTR_AMBIENT,  // ambient light type
		gray, black, black,    // color for ambient term only
		posL, dirL,            // no need for pos or dir
		0,0,0,                 // no need for attenuation
		0,0,0);                // spotlight info NA


	dirL.SetX(-1);
	dirL.SetY(0);
	dirL.SetZ(-1);
	dirL.SetW(0);
	// directional light
	lightMgr[INFINITE_LIGHT_INDEX]->Init(
		INFINITE_LIGHT_INDEX,  
		LIGHTV1_STATE_ON,      // turn the light on
		LIGHTV1_ATTR_INFINITE, // infinite light type
		black, gray, black,    // color for diffuse term only
		posL, dirL,				// need direction only
		0,0,0,                 // no need for attenuation
		0,0,0);                // spotlight info NA

	posL.SetX(0);
	posL.SetY(200);
	posL.SetZ(0);
	posL.SetW(0);
	// point light
	lightMgr[POINT_LIGHT_INDEX]->Init(
		POINT_LIGHT_INDEX,
		LIGHTV1_STATE_ON,      // turn the light on
		LIGHTV1_ATTR_POINT,    // pointlight type
		black, green, black,   // color for diffuse term only
		posL, dirL,     // need pos only
		0,.001,0,              // linear attenuation only
		0,0,1);                // spotlight info NA

	VECTOR4D slight_pos = {0,200,0,0};
	VECTOR4D slight_dir = {-1,0,-1,0};

	dirL.SetX(-1);
	dirL.SetY(0);
	dirL.SetZ(-1);
	dirL.SetW(0);

	posL.SetX(0);
	posL.SetY(200);
	posL.SetZ(0);
	posL.SetW(0);

	// spot light
	lightMgr[SPOT_LIGHT_INDEX]->Init(
		SPOT_LIGHT_INDEX,
		LIGHTV1_STATE_ON,			// turn the light on
		LIGHTV1_ATTR_SPOTLIGHT2,	// spot light type 2
		black, red, black,			// color for diffuse term only
		posL, dirL, // need pos only
		0,.001,0,					// linear attenuation only
		0,0,1);						// spotlight powerfactor only


	// create lookup for lighting engine
	RgbTableInst::Inst()->Rgb_16_8_Indexed_Builder(DD_PIXEL_FORMAT565, m_ddraw.GetPalette(0));

	// return success
	return 0;

} // end Game_Init


int	CTankWar1::Game_Main()
{
	// this is the workhorse of your game it will be called
	// continuously in real-time this is like main() in C
	// all the calls for you game go here!

	static CMatrix44 mrot;   // general rotation matrix

	// these are used to create a circling camera
	static float view_angle = 0; 
	static float camera_distance = 6000;
	static CVector4d pos;
	static float tank_speed;
	static float turning = 0;

	// state variables for different rendering modes and help
	static int wireframe_mode = -1;
	static int backface_mode  = 1;
	static int lighting_mode  = 1;
	static int help_mode      = 1;

	
	char work_string[256]; // temp string
	//

	int index; // looping var

	// start the timing clock
	m_gameClock.Start_Clock();

	// clear the drawing surface 
	m_ddraw.Fill_Surface(BACK_SURFACE, 0);

		// draw the sky
	m_graphGdi.Draw_Rectangle(0,0, m_WndWidth-1, m_WndHeight/2, RGB16Bit(0,140,192));

	// draw the ground
	m_graphGdi.Draw_Rectangle(0,m_WndHeight/2, m_WndWidth-1, m_WndHeight-1, RGB16Bit(103,62,3));

	// read keyboard and other devices here
	m_gameInput.Read_Keyboard();

	// game logic here...
	rend_list.Reset();

	// turbo
	if (m_gameInput.GetKeyState(DIK_SPACE))
		tank_speed = 5*TANK_SPEED;
	else
		tank_speed = TANK_SPEED;

	// forward/backward
	if (m_gameInput.GetKeyState(DIK_UP))
	{
		// move forward
		cam.m_pos.vector[X] += tank_speed * CTrigMath::Fast_Sin(cam.m_dir[Y]);
		cam.m_pos.vector[Z] += tank_speed * CTrigMath::Fast_Cos(cam.m_dir[Y]);
	} // end if

	if (m_gameInput.GetKeyState(DIK_DOWN))
	{
		// move backward
		cam.m_pos.vector[X] -= tank_speed * CTrigMath::Fast_Sin(cam.m_dir[Y]);
		cam.m_pos.vector[Z] -= tank_speed * CTrigMath::Fast_Cos(cam.m_dir[Y]);
	} // end if

	// rotate
	if (m_gameInput.GetKeyState(DIK_RIGHT))
	{
		cam.m_dir.vector[Y] += 3; 

		// add a little turn to object
		if ((turning+=2) > 15)
			turning=15;

	} // end if

	if (m_gameInput.GetKeyState(DIK_LEFT))
	{
		cam.m_dir.vector[Y] -= 3; 

		// add a little turn to object
		if ((turning-=2) < -15)
			turning=-15;

	} // end if
	else // center heading again
	{
		if (turning > 0)
			turning-=1;
		else
			if (turning < 0)
				turning+=1;

	} // end else

	//==
	// modes and lights

	// wireframe mode
	if (m_gameInput.GetKeyState(DIK_W))
	{
		// toggle wireframe mode
		wireframe_mode = -wireframe_mode;
		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if

	// backface removal
	if (m_gameInput.GetKeyState(DIK_B))
	{
		// toggle backface removal
		backface_mode = -backface_mode;
		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if

	// lighting
	if (m_gameInput.GetKeyState(DIK_L))
	{
		// toggle lighting engine completely
		lighting_mode = -lighting_mode;
		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if


	// toggle ambient light
	if (m_gameInput.GetKeyState(DIK_A))
	{
		// toggle ambient light
		if (lightMgr[AMBIENT_LIGHT_INDEX]->state == LIGHTV1_STATE_ON)
			lightMgr[AMBIENT_LIGHT_INDEX]->state = LIGHTV1_STATE_OFF;
		else
			lightMgr[AMBIENT_LIGHT_INDEX]->state = LIGHTV1_STATE_ON;

		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if

	// toggle infinite light
	if (m_gameInput.GetKeyState(DIK_I))
	{
		// toggle ambient light
		if (lightMgr[INFINITE_LIGHT_INDEX]->state == LIGHTV1_STATE_ON)
			lightMgr[INFINITE_LIGHT_INDEX]->state = LIGHTV1_STATE_OFF;
		else
			lightMgr[INFINITE_LIGHT_INDEX]->state = LIGHTV1_STATE_ON;

		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if

	// toggle point light
	if (m_gameInput.GetKeyState(DIK_P))
	{
		// toggle point light
		if (lightMgr[POINT_LIGHT_INDEX]->state == LIGHTV1_STATE_ON)
			lightMgr[POINT_LIGHT_INDEX]->state = LIGHTV1_STATE_OFF;
		else
			lightMgr[POINT_LIGHT_INDEX]->state = LIGHTV1_STATE_ON;

		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if


	// toggle spot light
	if (m_gameInput.GetKeyState(DIK_S))
	{
		// toggle spot light
		if (lightMgr[SPOT_LIGHT_INDEX]->state == LIGHTV1_STATE_ON)
			lightMgr[SPOT_LIGHT_INDEX]->state = LIGHTV1_STATE_OFF;
		else
			lightMgr[SPOT_LIGHT_INDEX]->state = LIGHTV1_STATE_ON;

		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if

	// help menu
	if (m_gameInput.GetKeyState(DIK_H))
	{
		// toggle help menu 
		help_mode = -help_mode;
		m_gameClock.Wait_Clock(100); // wait, so keyboard doesn't bounce
	} // end if

	static float plight_ang = 0, slight_ang = 0; // angles for light motion

	// move point light source in ellipse around game world
	lightMgr[POINT_LIGHT_INDEX]->pos.SetX( 4000 * CTrigMath::Fast_Cos(plight_ang) );
	lightMgr[POINT_LIGHT_INDEX]->pos.SetY( 200 );
	lightMgr[POINT_LIGHT_INDEX]->pos.SetZ( 4000 * CTrigMath::Fast_Sin(plight_ang) );

	if ((plight_ang+=3) > 360)
		plight_ang = 0;

	// move spot light source in ellipse around game world
	lightMgr[SPOT_LIGHT_INDEX]->pos.SetX(2000 * CTrigMath::Fast_Cos(slight_ang));
	lightMgr[SPOT_LIGHT_INDEX]->pos.SetY(200);
	lightMgr[SPOT_LIGHT_INDEX]->pos.SetZ(2000 * CTrigMath::Fast_Sin(slight_ang));

	if ((slight_ang-=5) < 0)
		slight_ang = 360;
	//==

	// generate camera matrix
	cam.Build_Matrix_Euler(CAM_ROT_SEQ_ZYX);

	// lock the back buffer
	m_ddraw.Lock_Back_Surface();

	RECT clipRect = {0, 0, m_WndWidth-1, m_WndHeight-1};
	obj_tank.Init(m_ddraw.GetBackBuffer(), m_ddraw.GetBackLpitch(), clipRect, &cam);
	obj_player.Init(m_ddraw.GetBackBuffer(), m_ddraw.GetBackLpitch(), clipRect, &cam);
	obj_tower.Init(m_ddraw.GetBackBuffer(), m_ddraw.GetBackLpitch(), clipRect, &cam);
	obj_marker.Init(m_ddraw.GetBackBuffer(), m_ddraw.GetBackLpitch(), clipRect, &cam);
	rend_list.Init(m_ddraw.GetBackBuffer(), m_ddraw.GetBackLpitch(), clipRect, &cam);

	// insert the tanks in the world
	for (index = 0; index < NUM_TANKS; index++)
	{
		// reset the object (this only matters for backface and object removal)
		obj_tank.Reset();

		// generate rotation matrix around y axis
		XYZ_Rotation_MATRIX4X4(0, tanks[index][W], 0, mrot);

		// rotate the local coords of the object
		obj_tank.Transform(mrot, TRANSFORM_LOCAL_TO_TRANS,1);

		// set position of tank
		obj_tank.world_pos.vector[X] = tanks[index][X];
		obj_tank.world_pos.vector[Y] = tanks[index][Y];
		obj_tank.world_pos.vector[Z] = tanks[index][Z];

		// attempt to cull object   
		if (obj_tank.Cull(CULL_OBJECT_XYZ_PLANES))
		{
			// if we get here then the object is visible at this world position
			// so we can insert it into the rendering list
			// perform local/model to world transform
			obj_tank.Model_To_World(TRANSFORM_TRANS_ONLY);

			// perform lighting
			if (lighting_mode==1)
				lightMgr.Light_Obj4d_World16(obj_tank, 4);   

			// insert the object into render list
			rend_list.Insert_Obj4d(obj_tank);
			//rend_list.Push_Back(&obj_tank);
		} // end if

	} // end for

	// insert the player into the world
	// reset the object (this only matters for backface and object removal)
	obj_player.Reset();

	// set position of tank
	obj_player.world_pos.vector[X] = cam.m_pos[X] + 300 * CTrigMath::Fast_Sin(cam.m_dir[Y]);
	obj_player.world_pos.vector[Y] = cam.m_pos[Y] - 70;
	obj_player.world_pos.vector[Z] = cam.m_pos[Z] + 300 * CTrigMath::Fast_Cos(cam.m_dir[Y]);

	// generate rotation matrix around y axis
	XYZ_Rotation_MATRIX4X4(0, cam.m_dir[Y] + turning, 0, mrot);

	// rotate the local coords of the object
	obj_player.Transform(mrot, TRANSFORM_LOCAL_TO_TRANS,1);

	// perform world transform
	obj_player.Model_To_World(TRANSFORM_TRANS_ONLY);

	// perform lighting
	if (lighting_mode==1)
		lightMgr.Light_Obj4d_World16(obj_player, 4);   

	// insert the object into render list
	rend_list.Insert_Obj4d(obj_player, 0, lighting_mode);
	//rend_list.Push_Back(&obj_player);


	//
	// insert the towers in the world
	for (index = 0; index < NUM_TOWERS; index++)
	{
		// reset the object (this only matters for backface and object removal)
		obj_tower.Reset();

		// set position of tower
		obj_tower.world_pos.vector[X] = towers[index][X];
		obj_tower.world_pos.vector[Y] = towers[index][Y];
		obj_tower.world_pos.vector[Z] = towers[index][Z];

		// attempt to cull object   
		if (obj_tower.Cull(CULL_OBJECT_XYZ_PLANES))
		{
			// if we get here then the object is visible at this world position
			// so we can insert it into the rendering list
			// perform local/model to world transform
			obj_tower.Model_To_World();

			if (lighting_mode==1)
				lightMgr.Light_Obj4d_World16(obj_tower, 4);   

			// insert the object into render list
			rend_list.Insert_Obj4d(obj_tower);
		} // end if

	} // end for

	// seed number generator so that modulation of markers is always the same
	srand(13);
	//

	// insert the ground markers into the world
	for (int index_x = 0; index_x < NUM_POINTS_X; index_x++)
	{
		for (int index_z = 0; index_z < NUM_POINTS_Z; index_z++)
		{
			// reset the object (this only matters for backface and object removal)
			obj_marker.Reset();

			// set position of tower
			obj_marker.world_pos.vector[X] = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_x*POINT_SIZE;
			obj_marker.world_pos.vector[Y] = obj_marker.max_radius;
			obj_marker.world_pos.vector[Z] = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_z*POINT_SIZE;

			// attempt to cull object   
			if (obj_marker.Cull(CULL_OBJECT_XYZ_PLANES))
			{
				// if we get here then the object is visible at this world position
				// so we can insert it into the rendering list
				// perform local/model to world transform
				obj_marker.Model_To_World();
			
				if (lighting_mode==1)
					lightMgr.Light_Obj4d_World16(obj_marker, 4);   

				// insert the object into render list
				rend_list.Insert_Obj4d(obj_marker);
			} // end if

		}
	}// end for

	// remove backfaces
	if (backface_mode==1)
		rend_list.Remove_Backfaces();

	// apply world to camera transform
	rend_list.World_To_Camera();

	// apply camera to perspective transformation
	rend_list.Camera_To_Perspective();

	// apply screen transform
	rend_list.Perspective_To_Screen();

	sprintf(work_string,"pos:[%f, %f, %f] heading:[%f] elev:[%f], polys[%d]", 
		cam.m_pos[X], cam.m_pos[Y], cam.m_pos[Z], cam.m_dir[Y], cam.m_dir[X], CObjInst<Debug_Info_Frame>::Inst()->polys_rendered_per_frame); 

	m_graphGdi.Draw_Text(work_string, 0, m_WndHeight-20, RGB(0,255,0));

	sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d | BckFceRM [%s]", 
		((lighting_mode == 1) ? "ON" : "OFF"),
		lightMgr[AMBIENT_LIGHT_INDEX]->state,
		lightMgr[INFINITE_LIGHT_INDEX]->state, 
		lightMgr[POINT_LIGHT_INDEX]->state,
		lightMgr[SPOT_LIGHT_INDEX]->state,
		((backface_mode == 1) ? "ON" : "OFF"));

	m_graphGdi.Draw_Text(work_string, 0, m_WndHeight-34, RGB(0,255,0));


	// draw instructions
	m_graphGdi.Draw_Text("Press ESC to exit. Press <H> for Help.", 0, 0, RGB(0,255,0));

	// should we display help
	int text_y = 16;
	if (help_mode==1)
	{
		// draw help menu
		m_graphGdi.Draw_Text("<A>..............Toggle ambient light source.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<I>..............Toggle infinite light source.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<P>..............Toggle point light source.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<S>..............Toggle spot light source.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<W>..............Toggle wire frame/solid mode.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<B>..............Toggle backface removal.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<RIGHT ARROW>....Rotate player right.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<LEFT ARROW>.....Rotate player left.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<UP ARROW>.......Move player forward.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<DOWN ARROW>.....Move player backward.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<SPACE BAR>......Turbo.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<H>..............Toggle Help.", 0, text_y+=12, RGB(255,255,255));
		m_graphGdi.Draw_Text("<ESC>............Exit demo.", 0, text_y+=12, RGB(255,255,255));

	} // end help


	// draw instructions
		// draw instructions
	m_graphGdi.Draw_Text("Press ESC to exit. Use UP ARROW and DOWN ARROW to rotate.", 0, 0, RGB(0,255,0));

	// reset number of polys rendered
	CObjInst<Debug_Info_Frame>::Inst()->polys_rendered_per_frame = 0;

	// render the polygon list
	if (wireframe_mode  == 1)
		rend_list.Draw_Wire16();
	else
		rend_list.Draw_Solid16();

	// unlock the back buffer
	m_ddraw.Unlock_Back_Surface();

	// flip the surfaces
	m_ddraw.Flip(m_Window_client_x0, m_Window_client_y0);

	// sync to 30ish fps
	m_gameClock.Wait_Clock(30);

	// check of user is trying to exit
	if (KEY_DOWN(VK_ESCAPE) || m_gameInput.GetKeyState(DIK_ESCAPE))
	{
		PostMessage(m_hWnd, WM_DESTROY,0,0);

	} // end if

	return 0;
}

int	CTankWar1::Game_Shutdown()
{
	// this function is where you shutdown your game and
	// release all resources that you allocated

	// shut everything down

	// release all your resources created for the game here....


	CGameMain::Game_Shutdown();

	return 0;
}
